package com.authine.cloudpivot.ext.controller.VoucherCheckBill;

import cn.hutool.core.lang.Assert;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 *  凭证核查
 **/
@RestController
@RequestMapping("/public/VoucherCheckBillController")
@Slf4j
public class VoucherCheckBillController extends BaseController {


    @Autowired
    CloudSqlService sqlService;

    /**
     * 凭证核查  审批流完成后 数据写到-凭证核查 基础表 基础
     */
    @RequestMapping("finish")
    public void finish(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.VoucherCheckBill, bizId);

        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get("SheetVoucher");

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //获取审批人

//        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        String approval = "";

        for (Map<String, Object> map : list) {

            try {
                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //判断是否已存在
                String id = existsBizObject(map);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.VoucherCheckBase, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("基础表-人员信息基础作成功 ");
                //调用存储过程
                callProcess(id);

            } catch (Exception e) {
                String ComCode = (String) map.get("ComCode");
                String FYear = (String) map.get("FYear");
                log.info("基础表-错失标准信息基础操作失败 ComCode={},FYear={}", ComCode, FYear);
                log.info(e.getMessage(), e);
            }

        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.RpRecordVoid, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get("SheetRpRecordVoid");

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //获取审批人

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        for (Map<String, Object> map : list) {


            try {
                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //判断是否已存在
                String id = existsBizObject(data);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.RpRecordBase, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("基础表-人员信息基础作废操作成功 ");
                //调用存储过程
                callProcessToVoid(id);

            } catch (Exception e) {
                String funNumber = (String) map.get("funNumber");
                String rpstandardcode = (String) map.get("rpstandardcode");

                log.info("基础表-人员信息基础操作失败 funNumber={},rpstandardcode={}", funNumber, rpstandardcode);
                log.info(e.getMessage(), e);
            }

        }
    }


    /**
     * 调用存储过程
     * ------凭证核查
     * create proc   [dbo].[SyncVoucherCheck]       -----凭证核查
     * @number nvarchar(100),   ----凭证号
     * @id nvarchar(100),   ----ID  （id+entryid+assistentryid拼接）
     * @SuppCode NVARCHAR(100),   ----往来单位代码
     * @SuppName NVARCHAR(100),   ----往来单位
     * @ItemCode NVARCHAR(100),   ----事项代码
     * @Item NVARCHAR(100),   ----事项
     * @Dept NVARCHAR(100),   ----责任部门代码
     * @Person NVARCHAR(100),   ----责任人代码
     * @AuditDate nvarchar(50)
     * @Auditor nvarchar(50)    ----审批人   02.0100 张三
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.VoucherCheckBase);
        StringBuilder sql = new StringBuilder("SELECT Number,RelVoucher,SuppCode,SuppName,ItemCode,Item,RelDept,RelPerson,AuditDate,auditor from ")
                .append(tableName).append(" where id ='")
                //.append("' and oneLevelCode='").append(oneLevelCode)
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String Number = MapUtils.getString(map, "Number", "");
        String RelVoucher = MapUtils.getString(map, "RelVoucher", "");
        String SuppCode = MapUtils.getString(map, "SuppCode", "");
        String SuppName = MapUtils.getString(map, "SuppName", "");
        String ItemCode = MapUtils.getString(map, "ItemCode", "");

        String Item = MapUtils.getString(map, "Item", "");
        String RelDept = MapUtils.getString(map, "RelDept", "");
        String RelPerson = MapUtils.getString(map, "RelPerson", "");

//        Date DateTemp = (Date) map.get("Date");
//        String Date = DateTemp == null ? null : DateFormatUtils.format(DateTemp, "yyyy-MM-dd");
        LocalDateTime DateTemp = (LocalDateTime) map.get("Date");
        String Date =  ObjectUtils.isEmpty(DateTemp) ? "" : DateTemp.toLocalDate().toString();

        String auditer = MapUtils.getString(map, "auditer", "");


//        Assert.isFalse(StringUtils.isEmpty(RelevanceCompany),"{}不能为空","RelevanceCompany");
////        Assert.isFalse(firstDept==null ,"{}不能为空","firstDept");
//        Assert.isFalse(StringUtils.isEmpty(RelevanceBaseOrg),"{}不能为空","txtfuncode");
//        Assert.isFalse(StringUtils.isEmpty(posNumber),"{}不能为空","serial");
//        Assert.isFalse(StringUtils.isEmpty(rpstandardcode),"{}不能为空","rpstandardcode");
//        Assert.isFalse(StringUtils.isEmpty(personNumber),"{}不能为空","rpstandard");
//        Assert.isFalse(StringUtils.isEmpty(funNumber),"{}不能为空","desc");
//        Assert.isFalse(StringUtils.isEmpty(checkDeptNumber),"{}不能为空","rplevel");
//        Assert.isFalse(StringUtils.isEmpty(checkPersonNumber),"{}不能为空","relevantfilecode");
//        Assert.isFalse(StringUtils.isEmpty(Date),"{}不能为空","relevantfile");
//        Assert.isFalse(StringUtils.isEmpty(itemNumber),"{}不能为空","relevantfilecode");
//        Assert.isFalse(StringUtils.isEmpty(problemDesc),"{}不能为空","relevantfile");
//        Assert.isFalse(StringUtils.isEmpty(auditer),"{}不能为空","auditer");


        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncVoucherCheck   '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                Number,RelVoucher,SuppCode,SuppName,ItemCode,Item,RelDept,RelPerson, Date,  auditer);

        log.info("\n==========准备调用存储过程:{}", execSql);

        sqlService.execute(CloudSqlService.htEas, execSql);

        log.info("\n=============存储过程执行完成");

    }

    /**
     * 调用作废存储过程
     * --------人员信息记录   基础信息 作废
     * exec  QuestionRecordVoid
     *
     * @param bizId
     * @PersonCode nvarchar(100),    ----人员代码
     * @ItemCode nvarchar(100)     ----事项代码
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.RpRecordBase);
        StringBuilder sql = new StringBuilder("SELECT itemNumber,personNumber from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String personNumber = MapUtils.getString(map, "personNumber", "");
        String itemNumber = MapUtils.getString(map, "itemNumber", "");


        Assert.isFalse(StringUtils.isEmpty(itemNumber), "{}不能为空", "itemNumber");
        Assert.isFalse(StringUtils.isEmpty(personNumber), "{}不能为空", "personNumber");


        String execSql = String.format("exec [HG_LINK].[hg].[dbo].QuestionRecordVoid '%s','%s'",
                personNumber, itemNumber);

        log.info("\n==========准备调用作废存储过程:{}", execSql);

        sqlService.execute(CloudSqlService.htEas, execSql);

        log.info("\n=============作废存储过程执行完成");

    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {


        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity11";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.VoucherCheckBase);
        String RelVoucher = (String) data.get("id");
//        String itemNumber = (String) data.get("itemNumber");

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName)
                .append(" where RelVoucher='").append(RelVoucher)
//                .append("' and itemNumber='").append(itemNumber)
                .append("';");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     * 转换成  基础表-错失标准 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String auditer) {
        Map<String, Object> data = new HashMap<>();


        //公司
        data.put("ComCode", map.get("txtCom"));

        //凭证号
        data.put("Number", map.get("txtVoucher"));
        //记账日期
        data.put("BookDate", map.get("BookedDate"));

        //业务日期
        data.put("BizDate", map.get("BizDate"));

        //摘要
        data.put("Description", map.get("Description"));

        //科目代码
        data.put("AccountNumber", map.get("Account"));
        //科目名称
        data.put("AccountName", map.get("AccountName"));


        //核算项目
        data.put("AccountingItem", map.get("AccountingItem"));
        //币别
        data.put("Currency", map.get("Currency"));
        //原币金额
        data.put("OriAmt", map.get("OriAmt"));
        //借方
        data.put("Debt", map.get("Debt"));
        //贷方
        data.put("Credit", map.get("Credit"));
        //往来单位代码
        data.put("SuppCode", map.get("SuppCode"));
        //往来单位
        data.put("SuppName", map.get("Supp"));

        //事项代码
        data.put("ItemCode", map.get("ItemCode"));
        //事项
        data.put("Item", map.get("ItemCode"));
        //附件
        data.put("Attachment", map.get("Attachment"));
        //责任部门
        data.put("Dept", map.get("txtDept"));
        //责任人
        data.put("Person", map.get("txtPerson"));
        //责任人关联
        data.put("RelPerson", map.get("RelPerson"));
        //责任部门关联
        data.put("RelDept", map.get("RelDept"));

        //凭证关联
        data.put("RelVoucher", map.get("RelVoucher"));

        //审批时间
        data.put("auditDate", auditDate);
        //审批人
        data.put("auditer", auditer);

        return data;
    }
}

